package tanshiru2.controller;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import tanshiru2.entity.User;
import tanshiru2.service.UserService;
import tanshiru2.util.Assert;
import tanshiru2.util.EmailClient;
import tanshiru2.util.RespResult;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;
@Controller
//在类中使用，表示访问该控制器，必须以/login开头
@RequestMapping("/login")
public class LoginController {
    //注入发送邮件的工具类
    @Autowired
    protected UserService userService;
    @Autowired
    protected EmailClient emailClient;
    //声明会话对象
    //发送邮件后，验证码保存在会话中
    //当执行注册时，从会话中取出验证码数据跟用户输入的验证码做比对
    protected HttpSession session;
    //请求对象
    protected HttpServletRequest request;
    //相应的对象
    protected HttpServletResponse response;
    //必须是/login/sendEmailCode的URL,并且以POST方式提交的请求会到达该方法
    @PostMapping("/sendEmailCode")
    //表示服务端返回JSON数据【异步一般都是以JSON数据格式进行交互】
    @ResponseBody
    //JSON数据的返回，返回类型使用RespResult
    //String email  前端请求的参数名
    //Map<String, Object> map  会自动创建一个Map对象到方法中
    public RespResult sendEmailCode(String email, Map<String, Object> map) {
        System.out.println("22222");
        //先判断邮箱地址是否为空
        if (StrUtil.isEmpty(email)) {
            //只有静态方法可以使用类名直接访问
            //静态方法是以static修饰的方法
            //静态方法内部不能使用this关键字
            return RespResult.fail("邮箱不可为空");
        }
        // 发送验证码
        String verifyCode = emailClient.sendEmailCode(email);
        //把邮箱地址，验证码，有效期写入会话对象中
        map.put("email", email);
        map.put("code", verifyCode);
        map.put("time", new Date());
        //写入会话对象中
        session.setAttribute("EMAIL_CODE" + email, map);
        return RespResult.success("发送成功");
    }

    @PostMapping("/register")
    //表示服务端返回JSON数据【异步一般都是以JSON数据格式进行交互】
    @ResponseBody
    //JSON数据的返回，返回类型使用RespResult
    //String email  前端请求的参数名
    //Map<String, Object> map  会自动创建一个Map对象到方法中
    public RespResult register(User user, String code){
        //参数
        System.out.println(user);
        System.out.println(code);
        //1 参数的合法性验证
        String email = user.getUserEmail();
        if (Assert.isEmpty(email)){
            return RespResult.fail("请输入邮箱地址");
        }
        //其他参数的非空验证,自行补充
        //建议定义通用的工具类【静态方法】
        //如何验证输入的手机号码格式是否正确
        //如何验证输入的邮箱码格式是否正确

        //2 验证邮箱验证码是否正确【数值是否正确、是否在有效期之内】、数据存在session获取与删除
        Map<String, Object> codeMap = (Map<String, Object>) session.getAttribute("EMAIL_CODE" + email);
        //可能获取不到session
        if (Assert.isEmpty(codeMap)){
            return RespResult.fail("请先获取验证码");
        }
        String emailCode = (String) codeMap.get("code");
        if (!code.equals(codeMap.get("code"))){
            return RespResult.fail("邮箱验证码错误");
        }else {
            //验证有效期
            Date time = (Date) codeMap.get("time");
            if (System.currentTimeMillis() - time.getTime() >5*60*1000){
                //删除session
                session.removeAttribute("EMAIL_CODE"  + email);
                return RespResult.fail("验证码已失效，请重新获取");
            }
        }
        //3 验证账号是否唯一【一个账号只能被注册一次】、数据表要添加唯一索引
            //此时需要操作数据库，但是不能在控制层直接操作数据库
            //通过服务层（Service）去跟数据库交互
            //3/1在服务层定义一个方法
        User byUserAccount = userService.findUserByUserAccount(user);
        if (!Assert.isEmpty(byUserAccount)){
            return RespResult.fail("该账号已被注册");
        }
        //3.2写入操作
        if (userService.save(user)){
            return RespResult.success("注册成功");
        }
        return RespResult.fail("注册失败");


    }

    /**
     * 在每个子类方法调用之前先调用
     */
    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("1111");
        //初始化请求对象 响应对象 会话对象
        this.request = request;
        this.response = response;
        this.session = request.getSession(true);
        //loginUser = (User) session.getAttribute("loginUser");
        //session.setAttribute("kindList", illnessKindService.findList());
    }
    @PostMapping("/login")
    @ResponseBody
    public RespResult login(User user){
        System.out.println(user);
        if(Assert.isEmpty(user)||Assert.isEmpty(user.getUserAccount())||Assert.isEmpty(user.getUserPwd())){
            return RespResult.success("请完善登录信息");
        }
        User userByUserAccount = userService.findUserByUserAccount(user);
        if(Assert.isEmpty(userByUserAccount)){
            return RespResult.success("该账号未注册");
        }
        if(!userByUserAccount.getUserPwd().equals(user.getUserPwd())){
            return RespResult.success("密码错误");
        }
        userByUserAccount.setUpdateTime(new Date());
        userService.updateById(userByUserAccount);
        session.setAttribute("loginUser",userByUserAccount);
        return RespResult.success("登陆成功");
    }
}
